using Microsoft.Extensions.Logging;
using RAG.Application.Interfaces;
using System.Runtime.CompilerServices;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Builder;
using Serilog;
using Serilog.Events;

namespace RAG.Application.Services
{
    /// <summary>
    /// 日志服务实现 - Application层
    /// </summary>
    public class LogService : IAppLogService
    {
        private readonly ILogger<LogService> _logger;

        public LogService(ILogger<LogService> logger)
        {
            _logger = logger;
        }

        public void LogDebug(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
        {
            _logger.LogDebug("[{MemberName}:{LineNumber}] {Message}", memberName, sourceLineNumber, message);
        }

        public void LogInformation(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
        {
            _logger.LogInformation("[{MemberName}:{LineNumber}] {Message}", memberName, sourceLineNumber, message);
        }

        public void LogWarning(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
        {
            _logger.LogWarning("[{MemberName}:{LineNumber}] {Message}", memberName, sourceLineNumber, message);
        }

        public void LogError(string message, Exception? exception = null, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
        {
            if (exception != null)
            {
                _logger.LogError(exception, "[{MemberName}:{LineNumber}] {Message}", memberName, sourceLineNumber, message);
            }
            else
            {
                _logger.LogError("[{MemberName}:{LineNumber}] {Message}", memberName, sourceLineNumber, message);
            }
        }

        public void LogFatal(string message, Exception? exception = null, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
        {
            if (exception != null)
            {
                _logger.LogCritical(exception, "[{MemberName}:{LineNumber}] {Message}", memberName, sourceLineNumber, message);
            }
            else
            {
                _logger.LogCritical("[{MemberName}:{LineNumber}] {Message}", memberName, sourceLineNumber, message);
            }
        }

        public void LogBusinessOperation(string operation, string userId, string details, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
        {
            _logger.LogInformation("[BusinessOperation] [{MemberName}:{LineNumber}] Operation: {Operation}, UserId: {UserId}, Details: {Details}", 
                memberName, sourceLineNumber, operation, userId, details);
        }

        public void LogPerformance(string operation, long elapsedMilliseconds, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
        {
            _logger.LogInformation("[Performance] [{MemberName}:{LineNumber}] Operation: {Operation}, Elapsed: {ElapsedMs}ms", 
                memberName, sourceLineNumber, operation, elapsedMilliseconds);
        }
    }

    /// <summary>
    /// Serilog配置服务 - Application层
    /// </summary>
    public static class SerilogService
    {
        /// <summary>
        /// 配置Serilog
        /// </summary>
        public static IHostBuilder ConfigureSerilog(this IHostBuilder builder, IConfiguration configuration)
        {
            Log.Logger = new LoggerConfiguration()
                .ReadFrom.Configuration(configuration)
                .Enrich.FromLogContext()
                .Enrich.WithEnvironmentName()
                .Enrich.WithThreadId()
                .Enrich.WithProcessId()
                .WriteTo.Console(
                    outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} {Properties:j}{NewLine}{Exception}")
                .WriteTo.File(
                    path: "logs/rag-api-.log",
                    rollingInterval: RollingInterval.Day,
                    outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj} {Properties:j}{NewLine}{Exception}",
                    retainedFileCountLimit: 30)
                .WriteTo.Seq("http://localhost:5341") // 可选：配置Seq日志服务器
                .CreateLogger();

            return builder.UseSerilog();
        }

        /// <summary>
        /// 配置Serilog请求日志中间件
        /// </summary>
        public static IApplicationBuilder UseSerilogRequestLogging(this IApplicationBuilder app)
        {
            return app.UseSerilogRequestLogging(options =>
            {
                options.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
                {
                    diagnosticContext.Set("UserName", httpContext.User?.Identity?.Name ?? "anonymous");
                    diagnosticContext.Set("UserAgent", httpContext.Request.Headers["User-Agent"].ToString());
                    diagnosticContext.Set("RemoteIP", httpContext.Connection.RemoteIpAddress?.ToString());
                };
            });
        }
    }
} 